import numpy
import pandas
import operator
import time
from numpy import *
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
def knn(k,testdata,traindata,labels):
    traindatasize=traindata.shape[0]
    dif=numpy.tile(testdata,(traindatasize,1))-traindata
    sqdif=dif**2
    sumsqdif=sqdif.sum(axis=1)
    distance=sumsqdif**0.5
    sortdistance=distance.argsort()
    count={}
    for i in range(0,k):
        vote=labels[sortdistance[i]]
        count[vote]=count.get(vote,0)+1
    sortcount=sorted(count.items(),key=operator.itemgetter(1),reverse=True)
    return sortcount[0][0]

class Bayes:
    def __init__(self):
        self.length=-1
        self.labelcount=dict()
        self.vectorcount=dict()
    def fit(self,dataSet:list,labels:list):
        if(len(dataSet)!=len(labels)):
            raise ValueError("")
        self.length=len(dataSet[0])
        labelsnum=len(labels)
        norlabels=set(labels)
        for item in norlabels:
            thislabel=item
            self.labelcount[thislabel]=labels.count(thislabel)/labelsnum
        for vector,label in zip(dataSet,labels):
            if(label not in self.vectorcount):
                self.vectorcount[label]=[]
            self.vectorcount[label].append(vector)
        return self
    def btest(self,TestData,labelsSet):
        if(self.length==-1):
            raise ValueError("")
        lbDict=dict()
        for thislb in labelsSet:
            p=1
            alllabel=self.labelcount[thislb]
            allvector=self.vectorcount[thislb]
            vnum=len(allvector)
            allvector=numpy.array(allvector).T
            for index in range(0,len(TestData)):
                vector=list(allvector[index])
                p=p*vector.count(TestData[index])/vnum
            lbDict[thislb]=p*alllabel
        thislabel=sorted(lbDict,key=lambda x:lbDict[x],reverse=True)[0]
        return thislabel

fpath="F:\\pytmp\\yuanweihua\\iris.csv"
data=pandas.read_csv(fpath)
datax=data.iloc[:,0:4].as_matrix()
labels=data.iloc[:,4:5].as_matrix()
sx=preprocessing.scale(datax)
x_train,x_test,y_train,y_test=train_test_split(sx,labels,test_size=0.25,random_state=20)
for i in range(0,len(y_train)):
    if(y_train[i][0]=="setosa"):
        y_train[i][0]=1
    elif(y_train[i][0]=="versicolor"):
        y_train[i][0]=0
    elif(y_train[i][0]=="virginica"):
        y_train[i][0]=-1
for i in range(0,len(y_test)):
    if(y_test[i][0]=="setosa"):
        y_test[i][0]=1
    elif(y_test[i][0]=="versicolor"):
        y_test[i][0]=0
    elif(y_test[i][0]=="virginica"):
        y_test[i][0]=-1
y_train=y_train.flatten()
y_test=y_test.flatten()
knn_time1=time.time()
knn_n1=0
knn_n2=0
for i in range(0,len(x_test)):
    labelnum=knn(3,x_test[i],x_train,y_train)
    knn_n1=knn_n1+1
    if(y_test[i]==labelnum):
        knn_n2=knn_n2+1
knn_time2=time.time()
print("KNN算法   时间:"+str(knn_time2-knn_time1)+"   准确率:"+str(knn_n2/knn_n1))

knn_time3=time.time()
knn_n3=0
knn_n4=0
x_train=x_train.tolist()
y_train=y_train.tolist()
bayes=Bayes()
bayes.fit(x_train,y_train)
lb_set=set(y_test)
bayes.btest(x_test[0],lb_set)
for i in range(0,len(x_test)):
    labelnum=bayes.btest(x_test[i],lb_set)
    knn_n3=knn_n3+1
    if(y_test[i]==labelnum):
        knn_n4=knn_n4+1
knn_time4=time.time()
print("朴素贝叶斯算法   时间:"+str(knn_time4-knn_time3)+"   准确率:"+str(knn_n4/knn_n3))        

